package com.bcx.wind.workflow.pojo;

import com.bcx.wind.workflow.core.flow.NodeModel;
import com.bcx.wind.workflow.core.flow.node.TaskNode;
import com.bcx.wind.workflow.entity.WindTask;
import com.fasterxml.jackson.annotation.JsonIgnore;

import java.io.Serializable;
import java.util.LinkedList;
import java.util.List;

/**
 * 工作流任务详情实体
 *
 * @author zhanglei
 */
public class Task implements Serializable {

    /**
     * 节点名称
     */
    private String nodeId;

    /**
     * 节点显示名称
     */
    private String nodeName;


    /**
     * 任务节点相关属性
     */
    private TaskNodeAttr taskNodeAttr;


    /**
     * 当前任务节点模型
     */
    @JsonIgnore
    private NodeModel taskNode;

    /**
     * 当前任务实例
     */
    private WindTask windTask;


    /**
     * 当前任务配置信息
     */
    private WindConfig config;

    /**
     * 可以提交的路线
     */
    private List<Task>  submitPath = new LinkedList<>();

    /**
     * 已经提交的任务
     */
    private List<Task>  submitTasks = new LinkedList<>();

    /**
     * 已经驳回的任务
     */
    private List<Task>    rejectTask = new LinkedList<>();


    /**
     * 可以提交的节点
     */
    private List<Task>    canSubmitTasks = new LinkedList<>();


    /**
     * 可以驳回的节点
     */
    private List<Task>    canRejectTasks = new LinkedList<>();

    /**
     * 撤销任务
     */
    private Task    revokeTask;

    public Task(){}


    public Task(String nodeId,String nodeName){
        this.nodeId = nodeId;
        this.nodeName = nodeName;
    }

    public NodeModel getTaskNode() {
        return taskNode;
    }

    public Task setTaskNode(NodeModel taskNode) {
        this.taskNode = taskNode;
        if(taskNode != null){
            this.taskNodeAttr = new TaskNodeAttr()
                    .setNodeType(taskNode.nodeType())
                    .setInRouter(taskNode.inRouter());
            if(taskNode instanceof TaskNode){
                TaskNode node = (TaskNode) taskNode;
                this.taskNodeAttr.setFirstTask(node.isFirstTask())
                        .setInAnd(node.inAnd())
                        .setInDyna(node.inDyna())
                        .setInForkJoin(node.inForkJoin())
                        .setInOr(node.inOr())
                        .setJointly(node.jointly())
                        .setLastTask(node.isLastTask())
                        .setStrand(node.strand());
            }
        }
        return this;
    }

    public WindTask getWindTask() {
        return windTask;
    }

    public Task setWindTask(WindTask windTask) {
        this.windTask = windTask;
        return this;
    }

    public WindConfig getConfig() {
        return config;
    }

    public Task setConfig(WindConfig config) {
        this.config = config;
        return this;
    }

    public List<Task> getSubmitTasks() {
        return submitTasks;
    }

    public Task setSubmitTasks(List<Task> submitTasks) {
        this.submitTasks = submitTasks;
        return this;
    }

    public List<Task> getRejectTask() {
        return rejectTask;
    }

    public Task setRejectTask(List<Task> rejectTask) {
        this.rejectTask = rejectTask;
        return this;
    }

    public String getNodeId() {
        return nodeId;
    }

    public Task setNodeId(String nodeId) {
        this.nodeId = nodeId;
        return this;
    }

    public Task getRevokeTask() {
        return revokeTask;
    }

    public Task setRevokeTask(Task revokeTask) {
        this.revokeTask = revokeTask;
        return this;
    }

    public List<Task> getCanSubmitTasks() {
        return canSubmitTasks;
    }

    public Task setCanSubmitTasks(List<Task> canSubmitTasks) {
        this.canSubmitTasks = canSubmitTasks;
        return this;
    }

    public List<Task> getCanRejectTasks() {
        return canRejectTasks;
    }

    public Task setCanRejectTasks(List<Task> canRejectTasks) {
        this.canRejectTasks = canRejectTasks;
        return this;
    }

    public List<Task> getSubmitPath() {
        return submitPath;
    }

    public Task setSubmitPath(List<Task> submitPath) {
        this.submitPath = submitPath;
        return this;
    }

    public String getNodeName() {
        return nodeName;
    }

    public Task setNodeName(String nodeName) {
        this.nodeName = nodeName;
        return this;
    }


    public TaskNodeAttr getTaskNodeAttr() {
        return taskNodeAttr;
    }

    public Task setTaskNodeAttr(TaskNodeAttr taskNodeAttr) {
        this.taskNodeAttr = taskNodeAttr;
        return this;
    }

    @Override
    public int hashCode() {
        return this.getNodeId().hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Task){
            return ((Task) obj).getNodeId().equals(this.getNodeId());
        }
        return super.equals(obj);
    }

    public Task copy(){
        return new Task()
                .setNodeId(this.getNodeId())
                .setNodeName(this.getNodeName())
                .setWindTask(this.getWindTask())
                .setConfig(this.getConfig())
                .setTaskNode(this.getTaskNode())
                .setCanRejectTasks(this.getCanRejectTasks())
                .setCanSubmitTasks(this.getCanSubmitTasks())
                .setRejectTask(this.getRejectTask())
                .setRevokeTask(this.getRevokeTask())
                .setSubmitPath(this.getSubmitPath());
    }
}
